package com.zut.chat.service;

import com.zut.chat.entity.MessageRateLimitConfig;
import com.zut.chat.entity.UserMessageRate;
import com.zut.chat.entity.User;
import com.zut.chat.mapper.MessageRateLimitConfigMapper;
import com.zut.chat.mapper.UserMessageRateMapper;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.ZoneOffset;

import static com.zut.chat.entity.table.MessageRateLimitConfigTableDef.MESSAGE_RATE_LIMIT_CONFIG;
import static com.zut.chat.entity.table.UserMessageRateTableDef.USER_MESSAGE_RATE;

/**
 * 消息频率限制服务类
 */
@Slf4j
@Service
public class MessageRateLimitService extends ServiceImpl<MessageRateLimitConfigMapper, MessageRateLimitConfig> {

    @Autowired
    private UserMessageRateMapper userMessageRateMapper;

    /**
     * 检查用户是否超过发送频率限制
     */
    public boolean isRateLimited(String sessionId, User.UserType userType) {
        try {
            // 获取用户类型对应的频率限制配置
            MessageRateLimitConfig config = getConfigByUserType(userType.name());
            if (config == null || !config.getEnabled()) {
                return false; // 没有配置或未启用，不限制
            }

            // 获取用户当前的消息频率记录
            UserMessageRate userRate = getUserMessageRate(sessionId);
            if (userRate == null) {
                // 首次发送消息，创建记录
                createUserMessageRate(sessionId);
                return false;
            }

            LocalDateTime now = LocalDateTime.now();
            long currentMinute = now.toEpochSecond(ZoneOffset.UTC) / 60; // 当前分钟时间戳
            long currentHour = now.toEpochSecond(ZoneOffset.UTC) / 3600; // 当前小时时间戳

            // 检查是否需要重置计数器
            if (userRate.getCurrentMinute() == null || userRate.getCurrentMinute() != currentMinute) {
                // 新的分钟，重置分钟计数
                userRate.setCurrentMinute(currentMinute);
                userRate.setMessageCountMinute(0);
            }

            if (userRate.getCurrentHour() == null || userRate.getCurrentHour() != currentHour) {
                // 新的小时，重置小时计数
                userRate.setCurrentHour(currentHour);
                userRate.setMessageCountHour(0);
            }

            // 检查是否超过限制
            boolean minuteExceeded = userRate.getMessageCountMinute() >= config.getMaxMessagesPerMinute();
            boolean hourExceeded = userRate.getMessageCountHour() >= config.getMaxMessagesPerHour();

            if (minuteExceeded || hourExceeded) {
                log.warn("用户 {} 消息发送频率超限: 分钟内消息数={}, 小时内消息数={}",
                    sessionId, userRate.getMessageCountMinute(), userRate.getMessageCountHour());
                return true;
            }

            return false;
        } catch (Exception e) {
            log.error("检查消息频率限制时发生错误", e);
            return false; // 发生错误时不限制
        }
    }

    /**
     * 记录用户发送消息
     */
    @Async
    public void recordMessage(String sessionId) {
        try {
            UserMessageRate userRate = getUserMessageRate(sessionId);
            if (userRate == null) {
                createUserMessageRate(sessionId);
                userRate = getUserMessageRate(sessionId);
            }

            LocalDateTime now = LocalDateTime.now();
            long currentMinute = now.toEpochSecond(ZoneOffset.UTC) / 60;
            long currentHour = now.toEpochSecond(ZoneOffset.UTC) / 3600;

            // 更新计数器
            if (userRate.getCurrentMinute() == null || userRate.getCurrentMinute() != currentMinute) {
                userRate.setCurrentMinute(currentMinute);
                userRate.setMessageCountMinute(1);
            } else {
                userRate.setMessageCountMinute(userRate.getMessageCountMinute() + 1);
            }

            if (userRate.getCurrentHour() == null || userRate.getCurrentHour() != currentHour) {
                userRate.setCurrentHour(currentHour);
                userRate.setMessageCountHour(1);
            } else {
                userRate.setMessageCountHour(userRate.getMessageCountHour() + 1);
            }

            userRate.setLastMessageTime(now);
            userRate.setUpdateTime(now);

            userMessageRateMapper.update(userRate);
        } catch (Exception e) {
            log.error("记录用户消息发送时发生错误", e);
        }
    }

    /**
     * 获取用户类型对应的频率限制配置
     */
    public MessageRateLimitConfig getConfigByUserType(String userType) {
        return getOne(QueryWrapper.create()
                .where(MESSAGE_RATE_LIMIT_CONFIG.USER_TYPE.eq(userType)));
    }

    /**
     * 获取用户消息频率记录
     */
    private UserMessageRate getUserMessageRate(String sessionId) {
        return userMessageRateMapper.selectOneByQuery(QueryWrapper.create()
                .where(USER_MESSAGE_RATE.SESSION_ID.eq(sessionId)));
    }

    /**
     * 创建用户消息频率记录
     */
    private void createUserMessageRate(String sessionId) {
        LocalDateTime now = LocalDateTime.now();
        long currentMinute = now.toEpochSecond(ZoneOffset.UTC) / 60;
        long currentHour = now.toEpochSecond(ZoneOffset.UTC) / 3600;

        UserMessageRate userRate = UserMessageRate.builder()
                .sessionId(sessionId)
                .messageCountMinute(0)
                .messageCountHour(0)
                .currentMinute(currentMinute)
                .currentHour(currentHour)
                .lastMessageTime(now)
                .createTime(now)
                .updateTime(now)
                .build();

        userMessageRateMapper.insert(userRate);
    }

    /**
     * 更新频率限制配置
     */
    public boolean updateConfig(MessageRateLimitConfig config) {
        return updateById(config);
    }

    /**
     * 获取所有频率限制配置
     */
    public java.util.List<MessageRateLimitConfig> getAllConfigs() {
        return list();
    }

    /**
     * 清理过期的用户消息频率记录（可定期调用）
     */
    public void cleanupExpiredRecords() {
        try {
            LocalDateTime expireTime = LocalDateTime.now().minusDays(1); // 清理1天前的记录
            userMessageRateMapper.deleteByQuery(QueryWrapper.create()
                    .where(USER_MESSAGE_RATE.UPDATE_TIME.lt(expireTime)));
            log.info("清理过期的用户消息频率记录完成");
        } catch (Exception e) {
            log.error("清理过期的用户消息频率记录时发生错误", e);
        }
    }
}
